// by David Qiu <david@davidqiu.com>

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;


int main()
{
  clock_t start, finish, duration1, duration2;
  
  const unsigned int simple_mb = 12348765;
  const unsigned int special_mb = (unsigned int)5
                                  + ((unsigned int)6 << 4)
                                  + ((unsigned int)7 << 8)
                                  + ((unsigned int)8 << 12)
                                  + ((unsigned int)4 << 16)
                                  + ((unsigned int)3 << 20)
                                  + ((unsigned int)2 << 24)
                                  + ((unsigned int)1 << 28);
  unsigned int temp, temp2;
  
  
  // === Digit Fetch Test ===
  // Test options
  const unsigned int gft_fetch = 10000;
  const unsigned int gft_shift = 4 * 4;
  const int gft_loop = 10000000; // larger than +2
  
  // System information
  cout << "=== Digit Fetch Test ===" << endl;
  cout << "Fetch Division: " << gft_fetch << endl;
  cout << "Loop Times: " << gft_loop << endl; 
  
  // Test body
  duration1 = 0;
  duration2 = 0;
  printf("[Simple] number=%d\n", simple_mb); // simple: number
  printf("[Special] number=%x\n", special_mb); // special: number
  for(int i=0; i<gft_loop; ++i)
  {
    start = clock();
    temp = (simple_mb / gft_fetch) % 10;
    finish = clock();
    duration1 += finish - start;
    if(i==0) cout << "[Simple] fetch=" << temp << endl; // simple: fetch
    
    start = clock();
    temp = (special_mb >> gft_shift) & 0xf;
    finish = clock();
    duration2 += finish - start;
    if(i==0) cout << "[Special] fetch=" << temp << endl; // special: fetch
  }
  cout << "[simple] time=" << duration1 << "ms" << endl; // simple: time
  cout << "[special] time=" << duration2 << "ms" << endl; // special: time
  
  // System information footer
  cout << endl << endl;
  
  
  // === Operation A Test ===
  // Test options
  const int opat_loop = 10000000; // larger than +2
  
  // System information
  cout << "=== Operation A Test ===" << endl;
  cout << "Loop Times: " << opat_loop << endl; 
  
  // Test body
  duration1 = 0;
  duration2 = 0;
  printf("[Simple] number=%d\n", simple_mb); // simple: number
  printf("[Special] number=%x\n", special_mb); // special: number
  for(int i=0; i<opat_loop; ++i)
  {
    temp = simple_mb;
    start = clock();
    temp = (temp % 10000)*10000 + temp/10000;
    finish = clock();
    duration1 += finish - start;
    if(i==0) cout << "[Simple] opA=" << temp << endl; // simple: opA result
    
    temp = special_mb;
    start = clock();
    temp = ((temp & 0xffff) << 16) + (temp >> 16);
    finish = clock();
    duration2 += finish - start;
    if(i==0) printf("[Special] opA=%x\n", temp); // special: opA result
  }
  cout << "[simple] time=" << duration1 << "ms" << endl; // simple: time
  cout << "[special] time=" << duration2 << "ms" << endl; // special: time
  
  // System information footer
  cout << endl << endl;
  
  
  
  // Program exit 
  system("pause");
  return 0;
}
